#include "UnitTest++.h"
#include "Navigator.h"
#include "Trie.h"
#include <string>
#include <vector>

std::vector<std::string> traverseText(const std::string& text, Trie<std::string>& trie)
{
    Navigator<std::string> navigator(trie.getRoot());
    std::vector<std::string> words;

    for (int i = 0; i < text.size(); i++)
    {
        navigator = navigator.find(text.at(i));

        if (!(*navigator))
        {
            navigator.setNode(trie.getRoot());
        }
        else
        {
            if ((*navigator)->isWord())
            {
                std::string word = *((*navigator)->getValue());
                if (i < text.size() - 2)
                {
                    char nextCharacter = text.at(i + 2);
                    if (isspace(nextCharacter) || ispunct(nextCharacter))
                        words.push_back(word);
                }
                else words.push_back(word);
            }
        }
    }

    return words;
}

TEST(ShouldFindAWordThatExistInTheTrie)
{
    //arrange
    Trie<std::string> trie;
    std::string expected = "jorge";
    std::string text = "hi k am a developer";

    //act
    trie.addWord("hi", expected);
    std::vector<std::string> words = traverseText(text, trie);

    //assert
    CHECK_EQUAL(expected, words.at(0));
}

TEST(ShouldFindAWordThatDoesNotExistInTheTrie)
{
    //arrange
    Trie<std::string> trie;
    std::string expected = "jorge";
    std::string text = "Puppy";
    std::string wordFound;

    //act
    trie.addWord("hi", expected);
    std::vector<std::string> words = traverseText(text, trie);

    //assert
    CHECK(wordFound.empty());
}

TEST(ShouldFindSentencesInTheTrie)
{
    //arrange
    Trie<std::string> trie;
    std::string firstValue = "juan";
    std::string secondValue = "pablo";
    std::string text = "Pablo: hi i am Pablo\nJuan:hello Pablo";
    int expectedSize = 2;

    //act
    trie.addWord("hi i", firstValue);
    trie.addWord("hello Pablo", secondValue);
    std::vector<std::string> words = traverseText(text, trie);

    //assert
    CHECK_EQUAL(expectedSize, words.size());
}

TEST(ShouldCheckIfFoundValuesAreCorrect)
{
    //arrange
    Trie<std::string> trie;
    std::string firstValue = "hi i";
    std::string secondValue = "hello Pablo";
    std::string text = "Pablo: hi i am Pablo\nJuan:hello Pablo";

    //act
    trie.addWord("hi i", firstValue);
    trie.addWord("hello Pablo", secondValue);
    std::vector<std::string> words = traverseText(text, trie);

    //assert
    CHECK_EQUAL(firstValue, words.at(0));
    CHECK_EQUAL(secondValue, words.at(1));
}

TEST(ShouldIgnoreCaseSearchingWords)
{
    //arange
    Trie<std::string> trie;
    std::string value("daily");
    std::string text("please send your DailY reports");

    //act
    trie.addWord("daily", value);
    std::vector<std::string> words = traverseText(text, trie);

    //assert
    CHECK_EQUAL(value, words.at(0));
}